<script setup lang="ts">
import { LockClosedOutline, PersonOutline } from '@vicons/ionicons5';
import type { FormInst } from 'naive-ui';
import { to } from 'await-to-js';
import { useRouter } from 'vue-router';

import type { LoginData, TenantVO } from '@/api/types';
import { getCodeImg, getTenantList } from '@/api/login';
import logo from '@/assets/logo/logo.png';
import { useUserStore } from '@/store/modules/user';

const formRef = shallowRef<FormInst>();
const loginLoading = ref(false);

const userStore = useUserStore();
const router = useRouter();

const redirect = ref(undefined);

watch(
  () => router.currentRoute.value,
  (newRoute: any) => {
    redirect.value = newRoute.query && newRoute.query.redirect;
  },
  { immediate: true },
);

const loginForm = ref<LoginData>({
  tenantId: '000000',
  username: 'admin',
  password: 'admin123',
  rememberMe: false,
  code: '',
  uuid: '',
} as LoginData);

const codeUrl = ref('');

const rules = {
  username: { required: true, message: '请输入用户名！', trigger: 'blur' },
  password: { required: true, message: '请输入密码！', trigger: 'blur' },
  code: { required: true, message: '请输入验证码！', trigger: 'blur' },
};

function login() {
  formRef.value?.validate()
    .then(async () => {
      loginLoading.value = true;
      // 勾选了需要记住密码设置在 localStorage 中设置记住用户名和密码
      if (loginForm.value.rememberMe) {
        localStorage.setItem('tenantId', String(loginForm.value.tenantId));
        localStorage.setItem('username', String(loginForm.value.username));
        localStorage.setItem('password', String(loginForm.value.password));
        localStorage.setItem('rememberMe', String(loginForm.value.rememberMe));
      } else {
        // 否则移除
        localStorage.removeItem('tenantId');
        localStorage.removeItem('username');
        localStorage.removeItem('password');
        localStorage.removeItem('rememberMe');
      }

      const [err] = await to(userStore.login(loginForm.value));
      if (!err) {
        const redirectUrl = redirect.value || '/';
        await router.push(redirectUrl);
        loginLoading.value = false;
      } else {
        loginLoading.value = false;
        // 重新获取验证码
        if (captchaEnabled.value) {
          await getCode();
        }
      }
    })
    .catch(() => {
      loginLoading.value = false;
    });
}

// 验证码开关
const captchaEnabled = ref(true);
// 租户开关
const tenantEnabled = ref(true);

// 租户列表
const tenantList = ref<TenantVO[]>([]);

/**
 * 获取验证码
 */
async function getCode() {
  const res = await getCodeImg();
  const { data } = res;
  captchaEnabled.value = data.captchaEnabled === undefined ? true : data.captchaEnabled;
  if (captchaEnabled.value) {
    codeUrl.value = `data:image/gif;base64,${data.img}`;
    loginForm.value.uuid = data.uuid;
  }
}

/**
 * 获取租户列表
 */
async function initTenantList() {
  const { data } = await getTenantList();
  tenantEnabled.value = data.tenantEnabled === undefined ? true : data.tenantEnabled;
  if (tenantEnabled.value) {
    tenantList.value = data.voList;
    if (tenantList.value != null && tenantList.value.length !== 0) {
      loginForm.value.tenantId = tenantList.value[0].tenantId;
    }
  }
}

function getLoginData() {
  const tenantId = localStorage.getItem('tenantId');
  const username = localStorage.getItem('username');
  const password = localStorage.getItem('password');
  const rememberMe = localStorage.getItem('rememberMe');
  loginForm.value = {
    tenantId: tenantId === null ? String(loginForm.value.tenantId) : tenantId,
    username: username === null ? String(loginForm.value.username) : username,
    password: password === null ? String(loginForm.value.password) : String(password),
    rememberMe: rememberMe === null ? false : Boolean(rememberMe),
  } as LoginData;
}

onMounted(() => {
  getCode();
  initTenantList();
  getLoginData();
});
</script>

<template>
  <div class="login-box">
    <div class="animate__animated animate__lightSpeedInLeft login-box-container shadow-lg">
      <div class="login-box-top">
        <div class="login-box-top-logo">
          <img :src="logo" alt="logo" />
        </div>
        <div class="login-box-top-desc">
          <NGradientText type="primary">
            123456
          </NGradientText>
        </div>
      </div>
      <div class="login-box-form">
        <NForm ref="formRef" label-placement="left" size="large" :model="loginForm" :rules="rules">
          <NFormItem v-if="tenantEnabled" path="tenantId">
            <NSelect
              v-model:value="loginForm.tenantId"
              placeholder="请选择/输入公司名称"
              :options="tenantList"
              label-field="companyName"
              value-field="tenantId"
            />
          </NFormItem>
          <NFormItem path="username">
            <NInput v-model:value="loginForm.username" placeholder="请输入用户名">
              <template #prefix>
                <NIcon size="18" color="#808695">
                  <PersonOutline />
                </NIcon>
              </template>
            </NInput>
          </NFormItem>
          <NFormItem path="password">
            <NInput
              v-model:value="loginForm.password"
              type="password"
              show-password-on="click"
              placeholder="请输入密码"
              @keyup.enter="login"
            >
              <template #prefix>
                <NIcon size="18" color="#808695">
                  <LockClosedOutline />
                </NIcon>
              </template>
            </NInput>
          </NFormItem>
          <NFormItem v-if="captchaEnabled" path="code">
            <div class="flex items-center">
              <NInput
                v-model:value="loginForm.code"
                placeholder="请输入验证码"
                @keyup.enter="login"
              />
              <img :src="codeUrl" class="login-code-img" alt="code" @click="getCode" />
            </div>
          </NFormItem>
          <div class="w-full flex justify-between items-center mb-4">
            <NCheckbox v-model:checked="loginForm.rememberMe">
              记住密码
            </NCheckbox>
            <span class="text-blue-500 cursor-pointer">忘记密码？</span>
          </div>
          <NFormItem>
            <NButton type="primary" size="large" :loading="loginLoading" block @click="login">
              登 录
            </NButton>
          </NFormItem>
        </NForm>
      </div>
    </div>
  </div>
</template>

<style lang="less" scoped>
.login-box {
  display: flex;
  flex-direction: row;
  height: 100vh;
  overflow: auto;
  justify-content: center;
  align-items: center;

  &-container {
    padding: 48px;
    max-width: 460px;
    min-width: 320px;
    background-color: #fff;
    border-radius: 18px;
  }

  &-top {
    margin-bottom: 48px;
    text-align: center;

    &-logo {
      margin-bottom: 24px;
    }

    &-desc {
      font-size: 28px;
      color: #808695;
    }
  }
}

@media (min-width: 768px) {
  .login-box {
    background-image: url('@/assets/images/login.svg');
    background-repeat: no-repeat;
    background-position: 50%;
    background-size: 100%;
  }
}

.login-code-img {
  height: 38px;
  margin-left: 12px;
  cursor: pointer;
  vertical-align: middle;
}
</style>
